/********************************************
  hsrb_eval.c

  Copyright (c) 2008, Jin Nishikawa
********************************************/
#include <ruby.h>
#include <errno.h>
#include "hsrb_eval.h"

static int hsrb_ruby_init() {
  if (!ruby_initialized) {
    ruby_init();
    ruby_init_loadpath();
    ruby_initialized = 1;
  }
  return ruby_initialized;
}

static VALUE hsrb_ruby_eval(int* state, char* str) {
  hsrb_ruby_init();
  return rb_eval_string_protect(str, state);
}

void* cpy(void* src, int len) {
  void* ret = malloc(len);
  if (ret == NULL) {
    return NULL;
  }
  memcpy(ret, src, len);
  return ret;
}

void* rb_eval(char* str, int* type) {
  VALUE val;
  int state = 0;
  int tmp = 0;
  void* ret = NULL;

  val = hsrb_ruby_eval(&state, str);
  errno = (state == 0) ? 0 : ((errno == 0) ? state : errno);
  if (errno == 0) {
    *type = TYPE(val);
  }
  switch (*type) {
    case T_STRING:
      ret = cpy((void*) RSTRING_PTR(val), RSTRING_LEN(val));
      break;
    case T_FIXNUM:
      tmp = FIX2INT(val);
      ret = cpy(&tmp, sizeof tmp);
      break;
    case T_NIL: case T_TRUE: case T_FALSE:
      break;
    default:
      errno = EINVAL;
  }
  return ret;
}
